package com.pacifico.telebusca.web.controladores;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import com.pacifico.telebusca.exception.Errores;
import com.pacifico.telebusca.web.beans.ValidacionErrores;
import com.pacifico.telebusca.web.facade.TeleBuscaFacade;
import com.pacifico.telebusca.web.form.ArchivoFormulario;
import com.pacifico.telebusca.web.util.Util;

@Controller
public class ControladorImportarAudios {

	private static Logger logger = Logger.getLogger(ControladorImportarAudios.class);
	
	@Autowired
	private TeleBuscaFacade teleBuscaFacade;

	private List<MultipartFile> archivos;
	List<String> nombreArchivos;
	private ValidacionErrores validacionErrores;
	

	private static final int BUFFER_SIZE = 4096;

	@RequestMapping(value = "/validar", method = RequestMethod.POST)
	public String validar(
			@ModelAttribute("archivoFormulario") ArchivoFormulario archivoFormulario,
			Model map, HttpServletRequest request) {
		Long inicio = System.currentTimeMillis();
		logger.info(" Iniciando validacion del archivo ");
		try {
			archivos = archivoFormulario.getFiles();
			nombreArchivos = new ArrayList<String>();
			String nombreArchivo;
			String archivoExtension;
			if (archivos != null && archivos.size() > 0) {
				for (MultipartFile multipartFile : archivos) {

					if (multipartFile.getBytes().length == 0) {
						map.addAttribute("error", Errores.MAP.get("I0001"));
						teleBuscaFacade.registrarAuditoria("I0001", "I0001");
						return "importaraudios";
					}

					nombreArchivo = multipartFile.getOriginalFilename();
					logger.info(" Iniciando validacion del archivo " + nombreArchivo);
					if ("".equals(nombreArchivo)) {						
						map.addAttribute("error", Errores.MAP.get("I0002"));
						teleBuscaFacade.registrarAuditoria("I0002", "I0002");
						return "importaraudios";
					}
					archivoExtension = nombreArchivo.substring(nombreArchivo
							.length() - 3);
					if (!"xml".equals(archivoExtension)) {
						map.addAttribute("error", Errores.MAP.get("E2002"));
						teleBuscaFacade.registrarAuditoria("E2002", "E2002");
						return "importaraudios";
					}
					map.addAttribute("nombreArchivo", nombreArchivo);

					File tmpFile = new File(System
							.getProperty("java.io.tmpdir")
							+ System.getProperty("file.separator")
							+ multipartFile.getOriginalFilename());
					multipartFile.transferTo(tmpFile);
					try {
						validacionErrores = teleBuscaFacade
								.validarArchivoXml(tmpFile);
						request.getSession().setAttribute("validacionErrores",
								validacionErrores);
						Long fin = System.currentTimeMillis();
						Long total = fin - inicio;
						total = total/1000;
						teleBuscaFacade.registrarAuditoria("I0004", "I0004",total, tmpFile.getName() + "detalle validacion " + validacionErrores);

					} catch (Exception e) {
						e.printStackTrace();
						
						try {
							teleBuscaFacade.registrarAuditoria("I0005", "I0005",0L, e.getMessage());
						} catch (Exception ex){
							ex.printStackTrace();
						}
						throw e;
						
					}
					map.addAttribute("validacionErrores", validacionErrores);
					if (validacionErrores.getRegistrosNoValidos() == 0){
						map.addAttribute("mostrarBotonDescargar", false);
					} else {
						map.addAttribute("mostrarBotonDescargar", true);
					}
					
					if (validacionErrores.getRegistrosValidos() == 0){
						map.addAttribute("mostrarBotonProcesar", false);
					} else {
						map.addAttribute("mostrarBotonProcesar", true);
					}
						
				}
			} else {
				map.addAttribute("error", "Debe Seleccion un archivo");
			}
		} catch (Exception e) {
			e.printStackTrace();
			
			if (e.getMessage().contains("Base de datos no disponible.")){
				map.addAttribute("error", Errores.MAP.get("E0002"));				
				return "importaraudios";
			}
			
			if (e.getCause()!=null){
				if (e.getCause().getCause()!=null){
					if(!e.getCause().getCause().getMessage().equals("")){
						if(e.getCause().getCause().getMessage().contains("Cannot release connection")||
								e.getCause().getCause().getMessage().contains("Cannot open connection")||
								e.getCause().getCause().getMessage().contains("JDBC rollback failed")){
							map.addAttribute("error", Errores.MAP.get("E0002"));				
							return "importaraudios";
						}
					}
				}	
			}
			map.addAttribute("error", Errores.MAP.get("I0005"));			
			teleBuscaFacade.registrarAuditoria("I0005", "I0005",0L, e.getMessage());			
			
			return "importaraudios";

		}
		return "importaraudios";
	}

	@RequestMapping(value = "/descargar", method = RequestMethod.GET)
	public void descargarArchivoResgistroNoValidos(HttpServletRequest request,
			HttpServletResponse response, Model map) throws IOException {

		try {
			File downloadFile = null;
			FileInputStream inputStream = null;
			this.validacionErrores = (ValidacionErrores) request.getSession()
					.getAttribute("validacionErrores");
			downloadFile = teleBuscaFacade
					.descargarArchivoResgistroNoValidos(validacionErrores
							.getAudiosNoValidos());

			inputStream = new FileInputStream(downloadFile);
			String mimeType = "application/octet-stream";			
			response.setContentType(mimeType);
			response.setContentLength((int) downloadFile.length());
			String headerKey = "Content-Disposition";
			String headerValue = String.format("attachment; filename=\"%s\"",
					downloadFile.getName());
			response.setHeader(headerKey, headerValue);

			OutputStream outStream = response.getOutputStream();

			byte[] buffer = new byte[BUFFER_SIZE];
			int bytesRead = -1;

			while ((bytesRead = inputStream.read(buffer)) != -1) {
				outStream.write(buffer, 0, bytesRead);
			}
			if (validacionErrores.getRegistrosValidos() == 0){
				map.addAttribute("mostrarBotonProcesar", false);
			} else {
				map.addAttribute("mostrarBotonProcesar", true);
			}
			
			
			inputStream.close();
			outStream.close();

			
			
			teleBuscaFacade.registrarAuditoria("I0006", "I0006");

		} catch (Exception e) {
			e.printStackTrace();
			
			
			
			map.addAttribute("error", e.getMessage());
			teleBuscaFacade.registrarAuditoria("I0007", "I0007",0L, e.getMessage());
			
		}

	}

	@RequestMapping(value = "/procesar", method = RequestMethod.GET)
	public String procesarArchivosValidos(HttpServletRequest request,
			HttpServletResponse response, Model map) throws IOException {
		Long inicio = System.currentTimeMillis();
		try {
			this.validacionErrores = (ValidacionErrores) request.getSession()
					.getAttribute("validacionErrores");
			teleBuscaFacade.guardarAudios(this.validacionErrores
					.getAudiosValidos(), Util
					.obtenerNombreUsuario(SecurityContextHolder.getContext()));
			map.addAttribute("mensajes", "Se proceso los registros validos");
			Long fin = System.currentTimeMillis();
			Long total = fin - inicio;
			total = total/1000;
			if (validacionErrores.getRegistrosValidos() == 0){
				map.addAttribute("mostrarBotonProcesar", false);
			} else {
				map.addAttribute("mostrarBotonProcesar", true);
			}
			teleBuscaFacade.registrarAuditoria("I0008", "I0008",total,"");

		} catch (Exception e) {
			e.printStackTrace();
			if (e.getCause()!=null){
				if (e.getCause().getCause()!=null){
					if(!e.getCause().getCause().getMessage().equals("")){
						if(e.getCause().getCause().getMessage().contains("Cannot release connection")||
								e.getCause().getCause().getMessage().contains("Cannot open connection")||
								e.getCause().getCause().getMessage().contains("JDBC rollback failed")){
							map.addAttribute("error", Errores.MAP.get("E0002"));				
							return "importaraudios";
						}
					}
				}	
			}
			map.addAttribute("error", e.getMessage());
			teleBuscaFacade.registrarAuditoria("I0009", "I0009");
			return "importaraudios";
		}
		return "importaraudios";
	}

}
